package cn.wizzer.app.crown.commons.core;

import cn.wizzer.app.crown.commons.websocket.main.action.BaseNettyAction;
import cn.wizzer.app.crown.commons.websocket.main.filter.BaseNettyFilter;
import cn.wizzer.app.crown.commons.websocket.main.start.TcpServer;
import cn.wizzer.app.crown.commons.websocket.main.start.TcpServerStarter;
import cn.wizzer.app.crown.modules.models.CrownConfig;
import cn.wizzer.app.crown.modules.models.constant.CrownRedisConstant;
import cn.wizzer.app.crown.modules.services.impl.util.RedisUtil;
import cn.wizzer.framework.util.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import org.nutz.boot.AppContext;
import org.nutz.boot.NbApp;
import org.nutz.dao.Dao;
import org.nutz.dao.util.Daos;
import org.nutz.integration.jedis.JedisAgent;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Mirror;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.annotation.Modules;

import java.sql.Driver;
import java.sql.DriverManager;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

@IocBean(create = "init", depose = "depose")
@Modules(packages = "cn.wizzer")
public class DubboRpcCrownMainLauncher {
    private static final Log log = Logs.get();
    @Inject("refer:$ioc")
    private Ioc ioc;
    @Inject
    private Dao dao;
    @Inject
    private PropertiesProxy conf;
    @Inject
    private JedisAgent jedisAgent;
    @Inject("java:$conf.get('tcp.port')")
    private int port;
    @Inject
    private RedisService redisService;

    public static void main(String[] args) throws Exception {
        NbApp nb = new NbApp().setArgs(args).setPrintProcDoc(true);
        nb.getAppContext().setMainPackage("cn.wizzer");
        nb.run();
    }

    public void init() {
        RedisUtil.init(redisService);
        //通过POJO类创建表结构
        try {
            Daos.createTablesInPackage(dao, "cn.wizzer.app.crown", false);
            //通过POJO类修改表结构
            //Daos.migration(dao, "cn.wizzer.app.cms", true, false);
        } catch (Exception e) {
        }
        Ioc ioc = AppContext.getDefault().getIoc();
        //启动websocket
        TcpServerStarter.instance().setTcpServer(this.ioc.get(TcpServer.class)).start();
        //通过获取实例方式使ioc容器加载beans
        for (BaseNettyAction instance : BaseNettyAction.instances()) {
            System.out.println("netty-websocket action bean:" + ioc.get(instance.getClass()));
        }
        for (BaseNettyFilter instance : BaseNettyFilter.instances()) {
            System.out.println("netty-websocket filter bean:" + ioc.get(instance.getClass()));
        }
        // 启动时，将皇冠账号全部解锁
        String keys = CrownRedisConstant.CROWN_ACCOUNT + "*";
        List<String> accounts = RedisUtil.scan(keys);
        Iterator<String> iterator = accounts.iterator();
        while (iterator.hasNext()) {
            CrownConfig crownConfig = JSONUtil.parseStringToJavaBean(CrownConfig.class, redisService.get(iterator.next()));
            crownConfig.setLocked(false);
            redisService.set(CrownRedisConstant.CROWN_ACCOUNT + crownConfig.getUsername(), JSONObject.toJSONString(crownConfig));
            log.info("启动时皇冠账号解锁：" + crownConfig);
        }
    }


    public void depose() {
        // 非mysql数据库,或多webapp共享mysql驱动的话,以下语句删掉
        try {
            Mirror.me(Class.forName("com.mysql.jdbc.AbandonedConnectionCleanupThread")).invoke(null, "shutdown");
        } catch (Throwable e) {
        }
        // 解决com.alibaba.druid.proxy.DruidDriver和com.mysql.jdbc.Driver在reload时报warning的问题
        // 多webapp共享mysql驱动的话,以下语句删掉
        Enumeration<Driver> en = DriverManager.getDrivers();
        while (en.hasMoreElements()) {
            try {
                Driver driver = en.nextElement();
                String className = driver.getClass().getName();
                log.debug("deregisterDriver: " + className);
                DriverManager.deregisterDriver(driver);
            } catch (Exception e) {
            }
        }
    }
}
